/*
 * Copyright 2010 Mttang.com All right reserved. This software is the confidential and proprietary information of
 * Mttang.com ("Confidential Information"). You shall not disclose such Confidential Information and shall use it only
 * in accordance with the terms of the license agreement you entered into with Mttang.com.
 */
package com.mttang.sys.web.controller;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Random;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.context.MessageSource;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.RequestUtils;
import org.springframework.web.servlet.ModelAndView;

import com.mttang.framework.core.paginated.util.PagedFliper;
import com.mttang.framework.core.pojos.ServiceRequest;
import com.mttang.framework.core.pojos.ServiceResponse;
import com.mttang.framework.core.web.controller.BaseDispatcherMultiActionController;
import com.mttang.info.core.InfoFileConfigure;
import com.mttang.sys.biz.action.LoginAction;
import com.mttang.util.BASE64Encoder;
import com.mttang.util.InfoAppKeyConstant;
import com.mttang.util.InfoBeanConstant;
import com.mttang.util.InfoFileConfigureUtil;
import com.mttang.util.Md5;
import com.mttang.util.Tools;

/**
 * 类LoginActionController.java的实现描述：用于登入和忘记密码TODO 类实现描述
 * 
 * @author 郑斌 2010-6-7 下午03:00:48
 */
public class LoginActionController extends BaseDispatcherMultiActionController {

	
	private LoginAction loginAction;
	
	
    public void setLoginAction(LoginAction loginAction) {
		this.loginAction = loginAction;
	}

	/**
     * 登入
     * 
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    public ModelAndView login(HttpServletRequest request, HttpServletResponse response) throws Exception {

        // 找到本controller在APP中对应的Action.
        MessageSource msg = (MessageSource) this.getApplicationContext().getBean("messageSource");
      
        // 验证传来的数据
        Map<Object, Object> errorInfo = new HashMap<Object, Object>();
		if (request.getParameter("empno") == null
				|| request.getParameter("empno").trim().equals("")) {
            errorInfo.put("empno", msg.getMessage("sys.empno.null", null, Locale.CHINA));
        }
        if (request.getParameter("passWord") == null || request.getParameter("passWord").trim().equals("")) {
            errorInfo.put("passWord", msg.getMessage("sys.password.null", null, Locale.CHINA));
        }
        // 验证码验证
        String verify_key = "";
        String code = RequestUtils.getStringParameter(request, "code");
        Cookie cookies[] = request.getCookies();
        if (cookies != null) {
            for (int i = 0; i < cookies.length; i++) {
                Cookie c = cookies[i];
                if (c.getName().equals("VERIFY_KEY")) {
                    verify_key = c.getValue();
                    break;
                }
            }
        }
        String codeResult = this.passCode(code, verify_key);

        if (!"200".equals(codeResult)) {
            errorInfo.put("code", msg.getMessage("sys.code.error", null, Locale.CHINA));
        }
        if (errorInfo.size() > 0) {
            return new ModelAndView("login/login", "errorInfo", errorInfo);
        }
        // 获取从页面传过来的参数值.
        String empno = request.getParameter("empno").trim();
        String passWord = new Md5().getHexMD5Str(request.getParameter("passWord").trim());

        Map<String,Object> pMap = new HashMap<String,Object>();
        pMap.put("empno", empno);
        pMap.put("passWord", passWord);
      
        // 组装输入参数
        Map<Object, Object> condition = new HashMap<Object, Object>();
        condition.put("empno", empno);
        condition.put("passWord", passWord);
        // 日志
        Map<Object, Object> logMap = this.getLogParaInfo(request);
        logMap.put("OPTIONOR", empno);
        logMap.put("ITEM", "login");// 操作数据项：这里是游戏名称
        logMap.put("CLASS", "3");// 操作类型
        logMap.put("NEWMAP", condition);
        pMap.put("LOGMAP", logMap);
      
       
        // 将参数值绑定并传到APP中去
        try {
            if (logger.isInfoEnabled()) {
                logger.info("调用远程接口: loginAction");
            }
            // 调用app action的事件.
            Map<Object, Object> model = loginAction.login(pMap);
            String userid = String.valueOf(model.get("userid"));
            // 没有ID 说明没这个人回到登入页面
            if (userid == null || userid.equals("") || userid.equals("null")) {
                return new ModelAndView("login/login", "message", msg.getMessage("sys.login.error", null, Locale.CHINA));
            }
            request.getSession().setAttribute("user", model);
 //           loginSetKey(request);// 绑定默认外键
            return new ModelAndView("index", "success_view", null);
        } catch (Exception e) {
            logger.error(e);
            return new ModelAndView("error", "bean", "Oops, error occur...");
        }
    }

    /**
     * 跳转到登入页面
     * 
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    public ModelAndView loginJsp(HttpServletRequest request, HttpServletResponse response) throws Exception {

        return new ModelAndView("login/login", "success_view", null);
    }

    /**
     * 密码重置
     * 
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    public ModelAndView pass(HttpServletRequest request, HttpServletResponse response) throws Exception {
        MessageSource msg = (MessageSource) this.getApplicationContext().getBean("messageSource");
       
        // 验证传来的数据
        Map<Object, Object> errorInfo = new HashMap<Object, Object>();
        if (request.getParameter("empno") == null || request.getParameter("empno").trim().equals("")) {
            errorInfo.put("empno", msg.getMessage("sys.empno.null", null, Locale.CHINA));
        }
        if (errorInfo.size() > 0) {
            return new ModelAndView("login/login", "message", errorInfo);
        }

        // 获取从页面传过来的参数值.
        String empno = request.getParameter("empno").trim();
        // 组装输入参数

        if ("admin".equals(empno)) {
            return new ModelAndView("login/login", "message", msg.getMessage("sys.login.admin", null, Locale.CHINA));
        }
        Map<String, Object> condition = new HashMap<String, Object>();
        condition.put("empno", empno);
        StringBuffer buf = new StringBuffer();
        for (int i = 0; i < 6; i++) {
            int a = new Random().nextInt(9);
            buf.append(a);
        }
        condition.put("subject", msg.getMessage("sys.email.subject", null, Locale.CHINA));
        condition.put("content", msg.getMessage("sys.email.content", null, Locale.CHINA) + buf.toString());
        condition.put("pass", new Md5().getHexMD5Str(buf.toString()));
        // 日志
        Map<Object, Object> logMap = this.getLogParaInfo(request);
        logMap.put("ITEM", "忘记密码");// 操作数据项：这里是游戏名称
        logMap.put("CLASS", "1");// 操作类型
        logMap.put("NEWMAP", condition);
        condition.put("LOGMAP", logMap);
     
        ServiceResponse serviceResponse = null;
        // 将参数值绑定并传到APP中去
        try {
            if (logger.isInfoEnabled()) {
                logger.info("调用远程接口: loginAction");
            }
            // 调用app action的事件.
            Map<Object, Object> model = loginAction.pass(condition);
            String message = "";
            if (model.get("message") != null && !"".equals(model.get("message"))) {
                message = String.valueOf(model.get("message"));
                if ("1".equals(message)) {
                    return new ModelAndView("login/login", "message", message = msg.getMessage("sys.forgetpass.null",
                                                                                               null, Locale.CHINA));
                }
            }
            String b = String.valueOf(model.get("status"));
            if ("true".equals(b)) {
                message = msg.getMessage("sys.forgetpass.ok", null, Locale.CHINA);// 密码发送到您的邮箱！！
            } else {
                message = msg.getMessage("sys.forgetpass.error", null, Locale.CHINA);// 发送邮箱失败！！
            }
            request.setAttribute("empno", empno);
            return new ModelAndView("login/login", "message", message);
        } catch (Exception e) {
            logger.error(e);
            return new ModelAndView("login/login", "message", msg.getMessage("sys.error", null, Locale.CHINA));
        }

    }

    // 判断验证码是否输入正确
    private String passCode(String verifycode, String verify_key) {
        if (!StringUtils.hasLength(verifycode) || verifycode.length() != 4 || !StringUtils.hasLength(verify_key)) {
            return "401";
        }

        long l = Long.parseLong(verify_key, 16);
        long now = System.currentTimeMillis();
        if ((now - l) > 10 * 60 * 1000) {
            return "403";
        }

        StringBuilder yzm = new StringBuilder("");
        BASE64Encoder encode = new BASE64Encoder();
        String encodeStr = encode.encode(verify_key.getBytes());
        for (int i = encodeStr.length() - 1; i >= 0; i--) {
            if (Tools.isNumberOrLetter(encodeStr.charAt(i))) {
                yzm.append(encodeStr.charAt(i));
            }
            if (yzm.length() == 4) {
                break;
            }
        }
        if (yzm.toString().equalsIgnoreCase(verifycode)) {
            return "200";
        } else {
            return "400";
        }

    }

    /**
     * 日志IP和工号
     * 
     * @param request
     * @return
     */
    private Map<Object, Object> getLogParaInfo(HttpServletRequest request) {
        // 写日志用到的信息
        String ip = request.getHeader("x-forwarded-for");
        if ("unknown".equalsIgnoreCase(ip) || ip == null) {
            ip = request.getRemoteAddr();
        }

        Map<Object, Object> userMap = (Map<Object, Object>) request.getSession().getAttribute("user");
        Map<Object, Object> returnMap = new HashMap<Object, Object>();
        if (userMap == null || userMap.get("empno")==null) {
            returnMap.put("OPTIONOR", "  ");
        } else {
            returnMap.put("OPTIONOR", userMap.get("empno"));
        }
        returnMap.put("IP", ip);

        return returnMap;
    }

    public void loginChangeKey(HttpServletRequest request, HttpServletResponse response) throws Exception {
        try {
            String siteId = request.getParameter("siteId");
            InfoFileConfigure fileConfigure = settBySiteId(siteId);
            HttpSession session = request.getSession();
            session.setAttribute("infoFileConfigure", fileConfigure);
            session.setAttribute("siteId", siteId);
        } catch (Exception e) {
            response.getWriter().append(e.getMessage());
        }
    }

    public void loginSetKey(HttpServletRequest request) throws Exception {
        try {
            if (logger.isDebugEnabled()) {
                logger.debug("loginSetKey............");
            }
            HttpSession session = request.getSession();
            String siteId = String.valueOf(session.getAttribute("siteId"));
            if (siteId == null || siteId.equals("") || "null".equals(siteId)) {
                Map<Object, Object> map = setStageConfig(null);
                siteId = String.valueOf(map.get("id"));
                if (logger.isDebugEnabled()) {
                    logger.debug("loginSetKey >> siteId:" + siteId);
                }
            }
            InfoFileConfigure fileConfigure = settBySiteId(siteId);
            session.setAttribute("infoFileConfigure", fileConfigure);
            session.setAttribute("siteId", siteId);
            Map<String, String> stageMap = new HashMap<String, String>();
            List<Map<Object, Object>> list = listStage(null);
            for (Map<Object, Object> sMap : list) {
                String id = String.valueOf(sMap.get("id"));
                String name = String.valueOf(sMap.get("name"));
                stageMap.put(id, name);
            }
            session.setAttribute("stageMap", stageMap);
        } catch (Exception e) {
            logger.error(e.getStackTrace(),e);
        }
    }

    public Map<Object, Object> setStageConfig(String id) {
        List<Map<Object, Object>> data = listStage(id);
        if (data != null) return data.get(0);
        else return null;
    }

    public List<Map<Object, Object>> listStage(String id) {
//        ServiceRequest serviceRequest = new ServiceRequest();
//        serviceRequest.setRequestServiceId(InfoBeanConstant.ACTION_SITE);
//        serviceRequest.setParameter(InfoAppKeyConstant.K_method, "query");
        ServiceResponse serviceResponse = null;
        Map<Object, Object> condition = new HashMap<Object, Object>();
        Map<String, Object> map = new HashMap<String, Object>();
        if (id != null && id.length()>0) {
            map.put("id", id);
        }
        condition.put(InfoAppKeyConstant.K_parameter, map);
        condition.put(InfoAppKeyConstant.K_pageModel, new PagedFliper(Integer.MAX_VALUE, 1));
//        serviceRequest.setCurrentRequestObject(condition);
//        serviceResponse = getDispatcher().dispatcheService(serviceRequest);
//        Map<Object, Object> model = serviceResponse.getModel();
//        List<Map<Object, Object>> data = (List<Map<Object, Object>>) model.get(InfoAppKeyConstant.K_list);
    
        return null;
    }

    public InfoFileConfigure settBySiteId(String siteid) throws SecurityException, IllegalArgumentException,
                                                        NoSuchMethodException, IllegalAccessException,
                                                        InvocationTargetException, InstantiationException {
        ServiceRequest serviceRequest = new ServiceRequest();
        serviceRequest.setRequestServiceId(InfoBeanConstant.ACTION_SETTING);
        serviceRequest.setParameter(InfoAppKeyConstant.K_method, "query");
        ServiceResponse serviceResponse = null;
        Map<Object, Object> condition = new HashMap<Object, Object>();
        Map<String, Object> map = new HashMap<String, Object>();
        if (siteid != null && siteid.length()>0) {
            map.put("siteId", siteid);
        }
        condition.put(InfoAppKeyConstant.K_parameter, map);
        condition.put(InfoAppKeyConstant.K_pageModel, new PagedFliper(Integer.MAX_VALUE, 1));
        serviceRequest.setCurrentRequestObject(condition);
        serviceResponse = getDispatcher().dispatcheService(serviceRequest);
        Map<Object, Object> model = serviceResponse.getModel();
        List<Map> data = (List<Map>) model.get(InfoAppKeyConstant.K_list);
        Map<Object, Object> keyMap = new HashMap<Object, Object>();
        for (Map<Object, Object> oMap : data) {
            String key = String.valueOf(oMap.get("key"));
            Object value = oMap.get("value");
            // String first = key.charAt(0) + "";
            // first = first.toUpperCase();
            // key = first + key.substring(1);
            keyMap.put(key, value == null ? "" : value);
        }
        return mapToInfo(keyMap);
    }

    public InfoFileConfigure mapToInfo(Map<Object, Object> map) {
        return copyValueToInfo(InfoFileConfigureUtil.mapToInfo(map));
    }

    private InfoFileConfigure copyValueToInfo(InfoFileConfigure copy) {
        InfoFileConfigure temp = (InfoFileConfigure) this.getApplicationContext().getBean("infoFileConfigure");
        InfoFileConfigureUtil.copyBaseToInfo(copy, temp);
        return copy;
    }
}
